﻿// EditorApp.cs
//
// Copyright (c) 2007 Mike Strobel
//
// This source code is subject to the terms of the Microsoft Reciprocal License (Ms-RL).
// For details, see <http://www.opensource.org/licenses/ms-rl.html>.
//
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;

using Avalon.Windows.Controls;
using Avalon.Windows.Utility;

using DevComponents.WpfDock;
using DevComponents.WpfRibbon;

using Supremacy.Annotations;
using Supremacy.Economy;
using Supremacy.Entities;
using Supremacy.Orbitals;
using Supremacy.Tech;
using Supremacy.Types;
using Supremacy.Buildings;

namespace Supremacy.Editor
{
    /// <summary>
    /// Interaction logic for EditorWindow.xaml
    /// </summary>
    public partial class EditorWindow : INotifyPropertyChanged
    {
        #region Fields
        public static readonly RoutedUICommand BuildingDatabaseCommand;
        public static readonly RoutedUICommand CivDatabaseCommand;
        public static readonly RoutedUICommand FacilityDatabaseCommand;
        public static readonly RoutedUICommand RaceDatabaseCommand;
        public static readonly RoutedUICommand ShipDatabaseCommand;
        public static readonly RoutedUICommand StationDatabaseCommand;

        private readonly Dictionary<object, DockWindow> _objectWindowMap;
        private readonly StateScope _shutDownScope;
        #endregion

        #region Constructors
        static EditorWindow()
        {
            RaceDatabaseCommand = new RoutedUICommand(
                "Race Database",
                "RaceDatabase",
                typeof(EditorWindow));

            CivDatabaseCommand = new RoutedUICommand(
                "Civ Database",
                "CivDatabase",
                typeof(EditorWindow));

            BuildingDatabaseCommand = new RoutedUICommand(
                "Building Database",
                "BuildingDatabase",
                typeof(EditorWindow));

            FacilityDatabaseCommand = new RoutedUICommand(
                "Facility Database",
                "FacilityDatabase",
                typeof(EditorWindow));

            ShipDatabaseCommand = new RoutedUICommand(
                "Ship Database",
                "ShipDatabase",
                typeof(EditorWindow));

            StationDatabaseCommand = new RoutedUICommand(
                "Station Database",
                "StationDatabase",
                typeof(EditorWindow));

            RibbonCommandManager.Connect(
                EditorCommands.Exit,
                new ButtonDropDownCommandExtender(
                    "E_xit",
                    "/Resources/CloseTab32.png",
					"/Resources/Exit16.png"));

            RibbonCommandManager.Connect(
                DockWindow.CloseWindow,
                new ButtonDropDownCommandExtender(
                    "Close Window",
                    "/Resources/CloseTab32.png",
                    "/Resources/CloseTab32.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Close,
                new ButtonDropDownCommandExtender(
                    "Close Configuration",
                    "/Resources/Close32.png",
                    "/Resources/Close32.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.New,
                new ButtonDropDownCommandExtender(
                    "New Configuration",
                    "/Resources/BlankPage32.png",
                    "/Resources/BlankPage16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Open,
                new ButtonDropDownCommandExtender(
                    "Open Configuration",
                    "/Resources/Open32.png",
                    "/Resources/Open32.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Save,
                new ButtonDropDownCommandExtender(
                    "Save Configuration",
                    "/Resources/Save32.png",
                    "/Resources/Save16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.SaveAs,
                new ButtonDropDownCommandExtender(
                    "Save Configuration As...",
                    "/Resources/SaveAs32.png",
                    "/Resources/SaveAs32.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Cut,
                new ButtonDropDownCommandExtender(
                    "Cut",
                    "/Resources/Cut16.png",
                    "/Resources/Cut16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Copy,
                new ButtonDropDownCommandExtender(
                    "Copy",
                    "/Resources/Copy16.png",
                    "/Resources/Copy16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Paste,
                new ButtonDropDownCommandExtender(
                    "Paste",
                    "/Resources/Paste32.png",
                    "/Resources/Paste16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Delete,
                new ButtonDropDownCommandExtender(
                    "Delete",
                    "/Resources/Delete16.png",
                    "/Resources/Delete16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Find,
                new ButtonDropDownCommandExtender(
                    "Find",
                    "/Resources/Find16.png",
                    "/Resources/Find16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Replace,
                new ButtonDropDownCommandExtender(
                    "Replace",
                    "/Resources/Replace16.png",
                    "/Resources/Replace16.png"));

            RibbonCommandManager.Connect(
                EditorCommands.FindNext,
                new ButtonDropDownCommandExtender(
                    "Find Next",
                    "/Resources/FindNext16.png",
                    "/Resources/FindNext16.png"));

            RibbonCommandManager.Connect(
                ApplicationCommands.Help,
                new ButtonDropDownCommandExtender(
                    "Help",
                    "/Resources/Help16.png",
                    "/Resources/Help16.png"));

            RibbonCommandManager.Connect(
                RaceDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Races",
                    "/Resources/Species 8472.ico"));

            RibbonCommandManager.Connect(
                CivDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Factions",
                    "/Resources/United Federation Of Planets.ico"));

            RibbonCommandManager.Connect(
                BuildingDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Buildings",
                    "/Resources/Buildings.png"));

            RibbonCommandManager.Connect(
                FacilityDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Facilities",
                    "/Resources/Farm32.png"));

            RibbonCommandManager.Connect(
                ShipDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Ships",
                    "/Resources/Enterprise, U.S.S. E.ico"));

            RibbonCommandManager.Connect(
                StationDatabaseCommand,
                new ButtonDropDownCommandExtender(
                    "Stations",
                    "/Resources/Spacedock.ico"));

            RibbonCommandManager.Connect(
                EditorCommands.NewRace,
                new ButtonDropDownCommandExtender(EditorCommands.NewRace.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewCiv,
                new ButtonDropDownCommandExtender(EditorCommands.NewCiv.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewBuilding,
                new ButtonDropDownCommandExtender(EditorCommands.NewBuilding.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewShipyard,
                new ButtonDropDownCommandExtender(EditorCommands.NewShipyard.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewFacility,
                new ButtonDropDownCommandExtender(EditorCommands.NewFacility.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewShip,
                new ButtonDropDownCommandExtender(EditorCommands.NewShip.Text));

            RibbonCommandManager.Connect(
                EditorCommands.NewStation,
                new ButtonDropDownCommandExtender(EditorCommands.NewStation.Text));
        }

        public EditorWindow()
        {
            PresentationTraceSources.Refresh();
            PresentationTraceSources.SetTraceLevel(this, PresentationTraceLevel.Medium);

            InitializeComponent();

            EditorRibbon.ChangeColorScheme(eRibbonVisualStyle.Office2007Silver);
            EditorDock.ChangeColorScheme(eDockVisualStyle.Office2007Silver);

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.Exit,
                    ExitCommandExecuted));

            CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Save,
                    SaveCommandExecuted,
                    SaveCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Open,
                    OpenCommandExecuted,
                    OpenCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Close,
                    CloseCommandExecuted,
                    CloseCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    RaceDatabaseCommand,
                    RaceDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    CivDatabaseCommand,
                    CivDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    BuildingDatabaseCommand,
                    BuildingDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    FacilityDatabaseCommand,
                    FacilityDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    ShipDatabaseCommand,
                    ShipDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    StationDatabaseCommand,
                    StationDatabaseCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewRace,
                    NewRaceCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewCiv,
                    NewCivCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewBuilding,
                    NewBuildingCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewShipyard,
                    NewShipyardCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewFacility,
                    NewFacilityCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewShip,
                    NewShipCommandExecuted,
                    ContextCommandCanExecute));

            CommandBindings.Add(
                new CommandBinding(
                    EditorCommands.NewStation,
                    NewStationCommandExecuted,
                    ContextCommandCanExecute));

            CivListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteCivilizationExecuted,
                    GenerateCanDeleteHandler(CivListView)));

            RaceListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteRaceExecuted,
                    GenerateCanDeleteHandler(RaceListView)));

            BuildingListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteBuildingExecuted,
                    GenerateCanDeleteHandler(BuildingListView)));

            FacilityListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteFacilityExecuted,
                    GenerateCanDeleteHandler(FacilityListView)));

            ShipListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteShipExecuted,
                    GenerateCanDeleteHandler(ShipListView)));

            StationListView.CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Delete,
                    DeleteStationExecuted,
                    GenerateCanDeleteHandler(StationListView)));

            Loaded += EditorWindow_Loaded;

            EditorApp.Current.EditorContextChanged += OnEditorContextChanged;

            _objectWindowMap = new Dictionary<object, DockWindow>();
            _shutDownScope = new StateScope();
        }

        private void DeleteStationExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var design = StationListView.SelectedItem as TechObjectDesign;
            if (design == null)
                return;
            if (!ConfirmDeleteDesign(design))
                return;
            EditorContext.DeleteTechObjectDesign(design);
            ((ICollectionView)StationListView.ItemsSource).Refresh();
        }

        private void DeleteShipExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var design = ShipListView.SelectedItem as TechObjectDesign;
            if (design == null)
                return;
            if (!ConfirmDeleteDesign(design))
                return;
            EditorContext.DeleteTechObjectDesign(design);
            ((ICollectionView)ShipListView.ItemsSource).Refresh();
        }

        private void DeleteFacilityExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var design = FacilityListView.SelectedItem as TechObjectDesign;
            if (design == null)
                return;
            if (!ConfirmDeleteDesign(design))
                return;
            EditorContext.DeleteTechObjectDesign(design);
            ((ICollectionView)FacilityListView.ItemsSource).Refresh();
        }

        private void DeleteBuildingExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var design = BuildingListView.SelectedItem as TechObjectDesign;
            if (design == null)
                return;
            if (!ConfirmDeleteDesign(design))
                return;
            EditorContext.DeleteTechObjectDesign(design);
            ((ICollectionView)BuildingListView.ItemsSource).Refresh();
        }

        private static bool ConfirmDeleteDesign(TechObjectDesign design)
        {
            if (design == null)
                throw new ArgumentNullException("design");
            var confirmResult = TaskDialog.Show(
                Application.Current.MainWindow,
                String.Format("Delete \"{0}\"", design.Name),
                String.Format(
                    "Are you sure you want to delete \"{0}\"?",
                    design.Name),
                "Confirm Delete",
                TaskDialogButtons.Yes | TaskDialogButtons.No,
                TaskDialogIcon.Question);
            return (confirmResult.StandardButton == TaskDialogButtons.Yes);
        }

        private void DeleteRaceExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var race = RaceListView.SelectedItem as Race;
            if (race == null)
                return;
            var civsBasedOnRace = EditorContext.Civilizations.Where(o => o.Race == race);
            var confirmMessage = civsBasedOnRace.Any()
                                     ? String.Format(
                                           "The race \"{0}\" is referenced by one or more civilizations.\n"
                                           + "Deleting the race will delete those civilizations as well.\n\n"
                                           + "Are you sure you want to delete \"{0}\"?",
                                           race.PluralName)
                                     : String.Format(
                                           "Are you sure you want to delete the race \"{0}\"?",
                                           race.PluralName);
            var confirmResult = TaskDialog.Show(
                Application.Current.MainWindow,
                String.Format("Delete \"{0}\"", race.PluralName),
                confirmMessage,
                "Confirm Delete",
                TaskDialogButtons.Yes | TaskDialogButtons.No,
                TaskDialogIcon.Question);
            if (confirmResult.StandardButton == TaskDialogButtons.No)
                return;
            EditorContext.DeleteRace(race);
            ((ICollectionView)CivListView.ItemsSource).Refresh();
            ((ICollectionView)RaceListView.ItemsSource).Refresh();
        }

        private void DeleteCivilizationExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var civilization = CivListView.SelectedItem as Civilization;
            if (civilization == null)
                return;
            var confirmResult = TaskDialog.Show(
                Application.Current.MainWindow,
                String.Format("Delete \"{0}\"", civilization.ShortName),
                String.Format(
                    "Are you sure you want to delete the civilization \"{0}\"?",
                    civilization.ShortName),
                "Confirm Delete",
                TaskDialogButtons.Yes | TaskDialogButtons.No,
                TaskDialogIcon.Question);
            if (confirmResult.StandardButton == TaskDialogButtons.No)
                return;
            EditorContext.DeleteCivilization(civilization);
            ((ICollectionView)CivListView.ItemsSource).Refresh();
        }

        private static CanExecuteRoutedEventHandler GenerateCanDeleteHandler(Selector selector)
        {
            return delegate(object sender, CanExecuteRoutedEventArgs e)
                   {
                       e.CanExecute = ((selector != null)
                                       && selector.IsKeyboardFocusWithin
                                       && (selector.SelectedItem != null));
                   };
        }

        private void EditorWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Loaded -= EditorWindow_Loaded;
            //LoadDockLayout();
        }

        private void NewStationCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var design = new StationDesign
                         {
                             DesignID = EditorContext.TechDatabase.GetNewDesignID(),
                             Key = identity
                         };

            EditorContext.TechDatabase.Add(design);

            ShowDockWindow(StationDatabaseDock);

            if (StationListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)StationListView.ItemsSource).Refresh();
            }
            else
            {
                StationListView.Items.Refresh();
            }
            StationListView.SelectedItem = design;
            StationListView.ScrollIntoView(design);

            ShowStationDocument(design);
        }

        private void NewShipCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var design = new ShipDesign
                         {
                             DesignID = EditorContext.TechDatabase.GetNewDesignID(),
                             Key = identity
                         };

            EditorContext.TechDatabase.Add(design);

            ShowDockWindow(ShipDatabaseDock);

            if (ShipListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)ShipListView.ItemsSource).Refresh();
            }
            else
            {
                ShipListView.Items.Refresh();
            }
            ShipListView.SelectedItem = design;
            ShipListView.ScrollIntoView(design);

            ShowShipDocument(design);
        }

        private void NewFacilityCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var design = new ProductionFacilityDesign
                         {
                             DesignID = EditorContext.TechDatabase.GetNewDesignID(),
                             Key = identity
                         };

            EditorContext.TechDatabase.Add(design);
            
            ShowDockWindow(FacilityDatabaseDock);

            if (FacilityListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)FacilityListView.ItemsSource).Refresh();
            }
            else
            {
                FacilityListView.Items.Refresh();
            }
            FacilityListView.SelectedItem = design;
            FacilityListView.ScrollIntoView(design);

            ShowFacilityDocument(design);
        }

        private void NewShipyardCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var design = new ShipyardDesign
                         {
                             DesignID = EditorContext.TechDatabase.GetNewDesignID(),
                             Key = identity
                         };

            EditorContext.TechDatabase.Add(design);

            ShowDockWindow(BuildingDatabaseDock);

            if (BuildingListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)BuildingListView.ItemsSource).Refresh();
            }
            else
            {
                BuildingListView.Items.Refresh();
            }
            BuildingListView.SelectedItem = design;
            BuildingListView.ScrollIntoView(design);

            ShowBuildingDocument(design);
        }

        private void NewBuildingCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var design = new BuildingDesign
                         {
                             DesignID = EditorContext.TechDatabase.GetNewDesignID(),
                             Key = identity
                         };

            EditorContext.TechDatabase.Add(design);
            
            ShowDockWindow(BuildingDatabaseDock);

            if (BuildingListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)BuildingListView.ItemsSource).Refresh();
            }
            else
            {
                BuildingListView.Items.Refresh();
            }
            BuildingListView.SelectedItem = design;
            BuildingListView.ScrollIntoView(design);

            ShowBuildingDocument(design);
        }

        private void NewCivCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Civilization civ = NewCivWindow.GetNewCiv();
            if (civ != null)
            {
                ShowDockWindow(RaceDatabaseDock);
                if (RaceListView.ItemsSource is ICollectionView)
                {
                    ((ICollectionView)RaceListView.ItemsSource).Refresh();
                }
                else
                {
                    RaceListView.Items.Refresh();
                }
                RaceListView.SelectedItem = civ.Race;
                RaceListView.ScrollIntoView(civ.Race);

                ShowDockWindow(CivDatabaseDock);

                if (CivListView.ItemsSource is ICollectionView)
                {
                    ((ICollectionView)CivListView.ItemsSource).Refresh();
                }
                else
                {
                    CivListView.Items.Refresh();
                }
                CivListView.SelectedItem = civ;
                CivListView.ScrollIntoView(civ);

                ShowCivDocument(civ);
            }
        }

        private void NewRaceCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            string identity, name;

            if (!NewItemWindow.GetNewItem(out identity, out name))
                return;

            var race = new Race
                       {
                           Key = identity,
                           PluralName = name,
                           SingularName = (name.EndsWith("s") ? name.Substring(0, name.Length - 1) : name)
                       };
            EditorContext.Races.Add(race);

            ShowDockWindow(RaceDatabaseDock);

            if (RaceListView.ItemsSource is ICollectionView)
            {
                ((ICollectionView)RaceListView.ItemsSource).Refresh();
            }
            else
            {
                RaceListView.Items.Refresh();
            }
            RaceListView.SelectedItem = race;
            RaceListView.ScrollIntoView(race);

            ShowRaceDocument(race);
        }

        private void ExitCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (_shutDownScope.IsWithin)
                return;
            using (_shutDownScope.Enter())
            {
                FocusManager.SetFocusedElement(this, this);
                if (EditorApp.Current.CloseContext(true))
                {
                    Close();
                }
            }
        }

        private static void OpenCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            FocusManager.SetFocusedElement(this, this);
            if (!_shutDownScope.IsWithin && !EditorApp.Current.CloseContext(true))
            {
                e.Cancel = true;
                return;
            }
            if (!e.Cancel)
            {
                CloseAllDocuments();
            }
        }

        private static void OpenCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (EditorApp.Current.CloseContext(true))
            {
                EditorApp.Current.LoadContext(null);
            }
        }

        private void ContextCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.EditorContext != null);
        }
        #endregion

        #region Properties
        [NotNull]
        public static EditorWindow Current
        {
            get { return (EditorWindow)Application.Current.MainWindow; }
        }

        public EditorContext EditorContext
        {
            get { return EditorApp.Current.EditorContext; }
        }
        #endregion

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Methods
        public void LogAction(string message)
        {
            OutputText.AppendText(message + Environment.NewLine);
            OutputText.ScrollToEnd();
        }

        internal static void ShowDockWindow(DockWindow window)
        {
            if (window != null)
            {
                if (!window.IsVisible)
                {
                    window.Open();
                }
                if (!window.IsSelected)
                {
                    window.IsSelected = true;
                }
                if (window.IsAutoHide)
                {
                    window.AutoHideOpen = true;
                }
                //else
                //{
                //    window.ParentGroup.UpdateVisibility();
                //    EditorDock.RestoreLastDockPosition(window.ParentGroup);
                //}
                window.FocusContent();
            }
        }

        private void BuildingDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(BuildingDatabaseDock);
        }

        private void CivDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(CivDatabaseDock);
        }

        public void CloseDocumentWindowForItem(object item)
        {
            DockWindow window;
            if (_objectWindowMap.TryGetValue(item, out window))
                window.Close();
        }

        private void CloseAllDocuments()
        {
            foreach (DockWindow document in EditorDock.GetDocuments())
            {
                document.Close();
            }
            _objectWindowMap.Clear();
        }

        private void CloseAllDockWindows()
        {
            CloseAllDocuments();
            foreach (DockWindow document in EditorDock.GetDockWindows())
            {
                document.Close();
            }
        }

        private void CloseCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.EditorContext != null);
        }

        private void CloseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (EditorApp.Current.CloseContext(true))
            {
                CloseAllDockWindows();
				//CommandManager.InvalidateRequerySuggested();
            }
        }

        private DockWindow CreateDocumentTab()
        {
            var window = new DockWindow
                         {
                             CanDockLeft = false,
                             CanDockRight = false,
                             CanDockTop = false,
                             CanDockBottom = false,
                             CanFloat = false,
                             CanDockAsDocument = true,
                             Name = ("__" + Guid.NewGuid().ToString().Replace("-", "")),
                             Background = SystemColors.WindowBrush
                         };

            window.Closed += OnDocumentClosed;

            DocumentWindowGroup.Items.Add(window);

            window.Open();

            //window.IsSelected = true;

            DocumentWindowGroup.UpdateVisibility();
            EditorDock.DockWindow(DocumentWindowGroup, eDockSide.Tab);

            //window.FocusContent();

            return window;
        }

        private void OnDocumentClosed(object sender, RoutedEventArgs e)
        {
            DockWindow window = sender as DockWindow;
            if (window != null)
            {
                _objectWindowMap.Remove(window.Tag);
                window.Closed -= OnDocumentClosed;
            }
        }

        private void FacilityDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(FacilityDatabaseDock);
        }

        private void OnEditorContextChanged(object sender, ParameterEventArgs<EditorContext> e)
        {
            CloseAllDockWindows();
            OnPropertyChanged("EditorContext");
            if (e.Parameter != null)
            {
                foreach (DockWindow window in UIHelpers.FindVisualDescendantsByType<DockWindow>(this))
                {
                    if (!DockSite.GetIsDocument(window))
                    {
                        ShowDockWindow(window);
                    }
                }
            }
        }

        private void RaceDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(RaceDatabaseDock);
        }

        private void RaceListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowRaceDocument(e.Parameter as Race);
            
        }

        private void ShowRaceDocument(Race race)
        {
            if (race != null)
            {
                if (_objectWindowMap.ContainsKey(race))
                {
                    ShowDockWindow(_objectWindowMap[race]);
                }
                else
                {
                    RaceEditor raceEditor = new RaceEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    Binding headerBinding = new Binding("Name");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    raceEditor.SetBinding(MaxWidthProperty, maxWidthBinding);

                    raceEditor.DataContext = race;
                    scrollViewer.Content = raceEditor;
                    window.Content = scrollViewer;

                    headerBinding.Source = race;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = race;
                    _objectWindowMap[race] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void SaveCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.EditorContext != null);
        }

        private void SaveCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (this.EditorContext != null)
                this.EditorContext.Save();
        }

        private void ShipDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(ShipDatabaseDock);
        }

        private void StationDatabaseCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            ShowDockWindow(StationDatabaseDock);
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        private void CivListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowCivDocument(e.Parameter as Civilization);
        }

        private void ShowCivDocument(Civilization civ)
        {
            if (civ != null)
            {
                if (_objectWindowMap.ContainsKey(civ))
                {
                    ShowDockWindow(_objectWindowMap[civ]);
                }
                else
                {
                    CivEditor civEditor = new CivEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    Binding headerBinding = new Binding("ShortName");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    civEditor.SetBinding(MaxWidthProperty, maxWidthBinding);

                    civEditor.DataContext = civ;
                    scrollViewer.Content = civEditor;
                    window.Content = scrollViewer;

                    headerBinding.Source = civ;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = civ;
                    _objectWindowMap[civ] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void BuildingListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowBuildingDocument(e.Parameter as BuildingDesign);
        }

        private void ShowBuildingDocument(TechObjectDesign design)
        {
            if (design != null)
            {
                if (_objectWindowMap.ContainsKey(design))
                {
                    ShowDockWindow(_objectWindowMap[design]);
                }
                else
                {
                    TechObjectEditor techObjectEditor = new TechObjectEditor();
                    BuildingEditor buildingEditor = new BuildingEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    StackPanel stackPanel = new StackPanel();
                    Binding headerBinding = new Binding("Name");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    stackPanel.Orientation = Orientation.Vertical;

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    stackPanel.SetBinding(MaxWidthProperty, maxWidthBinding);

                    techObjectEditor.DataContext = design;
                    stackPanel.Children.Add(techObjectEditor);

                    buildingEditor.DataContext = design;
                    stackPanel.Children.Add(buildingEditor);

                    if (design is ShipyardDesign)
                    {
                        var shipyardEditor = new ShipyardEditor
                                             {
                                                 DataContext = design
                                             };
                        stackPanel.Children.Add(shipyardEditor);
                    }

                    scrollViewer.Content = stackPanel;
                    window.Content = scrollViewer;

                    headerBinding.Source = design;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = design;
                    _objectWindowMap[design] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void FacilityListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowFacilityDocument(e.Parameter as ProductionFacilityDesign);
        }

        private void ShowFacilityDocument(TechObjectDesign design)
        {
            if (design != null)
            {
                if (_objectWindowMap.ContainsKey(design))
                {
                    ShowDockWindow(_objectWindowMap[design]);
                }
                else
                {
                    TechObjectEditor techObjectEditor = new TechObjectEditor();
                    FacilityEditor facilityEditor = new FacilityEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    StackPanel stackPanel = new StackPanel();
                    Binding headerBinding = new Binding("Name");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    stackPanel.Orientation = Orientation.Vertical;

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    stackPanel.SetBinding(MaxWidthProperty, maxWidthBinding);

                    techObjectEditor.DataContext = design;
                    stackPanel.Children.Add(techObjectEditor);

                    facilityEditor.DataContext = design;
                    stackPanel.Children.Add(facilityEditor);

                    scrollViewer.Content = stackPanel;
                    window.Content = scrollViewer;

                    headerBinding.Source = design;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = design;
                    _objectWindowMap[design] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void ShipListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowShipDocument(e.Parameter as ShipDesign);
        }

        private void ShowShipDocument(TechObjectDesign design)
        {
            if (design != null)
            {
                if (_objectWindowMap.ContainsKey(design))
                {
                    ShowDockWindow(_objectWindowMap[design]);
                }
                else
                {
                    TechObjectEditor techObjectEditor = new TechObjectEditor();
                    OrbitalEditor orbitalEditor = new OrbitalEditor();
                    ShipEditor shipEditor = new ShipEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    StackPanel stackPanel = new StackPanel();
                    Binding headerBinding = new Binding("Name");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    stackPanel.Orientation = Orientation.Vertical;

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    stackPanel.SetBinding(MaxWidthProperty, maxWidthBinding);

                    techObjectEditor.DataContext = design;
                    stackPanel.Children.Add(techObjectEditor);

                    orbitalEditor.DataContext = design;
                    stackPanel.Children.Add(orbitalEditor);

                    shipEditor.DataContext = design;
                    stackPanel.Children.Add(shipEditor);

                    scrollViewer.Content = stackPanel;
                    window.Content = scrollViewer;

                    headerBinding.Source = design;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = design;
                    _objectWindowMap[design] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void StationListView_SelectionActionRequested(object sender, ParameterRoutedEventArgs<object> e)
        {
            ShowStationDocument(e.Parameter as StationDesign);
        }

        private void ShowStationDocument(TechObjectDesign design)
        {
            if (design != null)
            {
                if (_objectWindowMap.ContainsKey(design))
                {
                    ShowDockWindow(_objectWindowMap[design]);
                }
                else
                {
                    TechObjectEditor techObjectEditor = new TechObjectEditor();
                    OrbitalEditor orbitalEditor = new OrbitalEditor();
                    StationEditor stationEditor = new StationEditor();
                    DockWindow window = CreateDocumentTab();
                    ScrollViewer scrollViewer = new ScrollViewer();
                    StackPanel stackPanel = new StackPanel();
                    Binding headerBinding = new Binding("Name");
                    Binding maxWidthBinding = new Binding("ViewportWidth");

                    stackPanel.Orientation = Orientation.Vertical;

                    scrollViewer.Focusable = false;
                    scrollViewer.FocusVisualStyle = null;
                    scrollViewer.CanContentScroll = false;
                    scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

                    maxWidthBinding.Source = scrollViewer;
                    stackPanel.SetBinding(MaxWidthProperty, maxWidthBinding);

                    techObjectEditor.DataContext = design;
                    stackPanel.Children.Add(techObjectEditor);

                    orbitalEditor.DataContext = design;
                    stackPanel.Children.Add(orbitalEditor);

                    stationEditor.DataContext = design;
                    stackPanel.Children.Add(stationEditor);

                    scrollViewer.Content = stackPanel;
                    window.Content = scrollViewer;

                    headerBinding.Source = design;
                    window.SetBinding(HeaderedContentControl.HeaderProperty, headerBinding);

                    window.Tag = design;
                    _objectWindowMap[design] = window;

                    ShowDockWindow(window);
                }
            }
        }

        private void StandardConfigurationButton_Click(object sender, RoutedEventArgs e)
        {
            ApplicationCommands.Open.Execute(null, this);
        }
    }
}